package Matrix.Medium;

import java.util.ArrayList;
import java.util.List;

public class LC0054 {
    public static List<Integer> spiralOrder(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        int leftBound = -1, topBound = -1, rightBound = n, bottomBound = m; // 划定边界，遍历时不可越过这些位置
        Direction currDir = Direction.right;
        ArrayList<Integer> ret = new ArrayList<>();

        while (leftBound + 1 < rightBound && topBound + 1 < bottomBound) {
            switch (currDir) {
                case right -> {
                    for (int i = leftBound + 1; i <= rightBound - 1; i++) {
                        ret.add(matrix[topBound + 1][i]);
                    }
                    topBound++;
                    currDir = currDir.getNext();
                    break;
                }
                case down -> {
                    for (int j = topBound + 1; j <= bottomBound - 1; j++) {
                        ret.add(matrix[j][rightBound - 1]);
                    }
                    rightBound--;
                    currDir = currDir.getNext();
                    break;
                }
                case left -> {
                    for (int i = rightBound - 1; i >= leftBound + 1; i--) {
                        ret.add(matrix[bottomBound - 1][i]);
                    }
                    bottomBound--;
                    currDir = currDir.getNext();
                    break;
                }
                case up -> {
                    for (int j = bottomBound - 1; j >= topBound + 1; j--) {
                        ret.add(matrix[j][leftBound + 1]);
                    }
                    leftBound++;
                    currDir = currDir.getNext();
                    break;
                }
            }
        }

        return ret;
    }

    enum Direction {
        right, down, left, up;

        public Direction getNext() {
            return Direction.values()[(this.ordinal() + 1) % Direction.values().length];
        }
    }

    public static void main(String[] args) {
        int[][] matrix = new int[][]{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
        List<Integer> result = spiralOrder(matrix);
        System.out.println(result);
    }
}
